package baseFx.log;

import baseFx.common.Action1T;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.apache.logging.log4j.core.appender.RollingFileAppender;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.spi.LoggerContext;
import org.slf4j.Logger;
import org.slf4j.impl.FxLog4jLoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

public class FxLog {
    public static String logDir = "logs";
    public static final List<String> allow = new ArrayList<>();
    public static Action1T<String> onNew;
    public static String msgLayout = "%d{yyyy.MM.dd HH:mm:ss.SSS}  %level\t-%T\t[%c{1.}.%M:%L] - %msg%n%xEx";
    public static boolean useJsonLayout;
    public static boolean singleFile;

    public static boolean isFxLog(String name) {
        if (allow.isEmpty()) {
            return true;
        }
        for (String item : allow) {
            String regex = item.replace(".", "\\.").replace("*", ".*");
            Pattern pat = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
            if (pat.matcher(name).find()) {
                return true;
            }
        }
        return false;
    }

    public static List<String> getNames() {
        List<String> names = new ArrayList<>();
        Set<LoggerContext> contexts = FxLog4jLoggerFactory.getInstance().getLoggerContexts();
        for (LoggerContext ctx : contexts) {
            Map<String, Logger> logs = FxLog4jLoggerFactory.getInstance().getLoggersInContext(ctx);
            for (String name : logs.keySet()) {
                if (isFxLog(name)) {
                    names.add(name);
                }
            }
        }
        return names;
    }

    public static FxLogSetting getFileSetting(String name) {
        Set<LoggerContext> contexts = FxLog4jLoggerFactory.getInstance().getLoggerContexts();
        for (LoggerContext ctx : contexts) {
            if (ctx instanceof org.apache.logging.log4j.core.LoggerContext) {
                org.apache.logging.log4j.core.LoggerContext context = (org.apache.logging.log4j.core.LoggerContext) ctx;
                Configuration config = context.getConfiguration();
                LoggerConfig conf = config.getLoggerConfig(name);
                Map<String, Appender> map = conf.getAppenders();
                Appender appender = map.get(name + "_file");
                if (appender != null) {
                    return (FxFilter) ((RollingFileAppender) appender).getFilter();
                }
            }
        }
        return null;
    }

    public static FxLogSetting getConsoleSetting(String name) {
        Set<LoggerContext> contexts = FxLog4jLoggerFactory.getInstance().getLoggerContexts();
        for (LoggerContext ctx : contexts) {
            if (ctx instanceof org.apache.logging.log4j.core.LoggerContext) {
                org.apache.logging.log4j.core.LoggerContext context = (org.apache.logging.log4j.core.LoggerContext) ctx;
                Configuration config = context.getConfiguration();
                LoggerConfig conf = config.getLoggerConfig(name);
                Map<String, Appender> map = conf.getAppenders();
                Appender appender = map.get(name + "_console");
                if (appender != null) {
                    return (FxFilter) ((ConsoleAppender) appender).getFilter();
                }
            }
        }
        return null;
    }
}
